//-----------------------------------------------------------------------
// <copyright file="LoggingProvider.cs" company="CodePlex">
//     Copyright (c) Doug Holland, CodePlex. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace CodePlex.Diagnostics.Providers
{
    using System;
    using System.Threading;
    using System.Reflection;
    using System.Diagnostics;

    using System.Security.Principal;

    /// <summary>
    /// Using the <see cref="M:CodePlex.Diagnostics.Providers.LoggingProvider.Log"/> method, log entries can be published using one or more logging providers.
    /// </summary>
    public static class LoggingProvider
    {
        #region public static Guid Log(string entry, LoggingPriority priority, LoggingType type, IIdentity identity)

        /// <summary>
        /// Publishes the specified <see cref="T:System.String"/> using the configured logging provider.
        /// </summary>
        /// <param name="entry">The <see cref="T:System.String"/> to be published.</param>
        /// <param name="priority">The <see cref="T:CodePlex.Diagnostics.LoggingPriority"/> of the specified log entry.</param>
        /// <param name="type">The <see cref="T:CodePlex.Diagnostics.LoggingType"/> of the specified log entry.</param>
        /// <param name="identity">The <see cref="T:System.Security.Principal.IIdentity"/> to associate with this log entry.</param>
        /// <returns>A <see cref="T:System.Guid"/> which can be used by users to reference the log entry.</returns>
        public static Guid Log(string entry, LoggingPriority priority, LoggingType type, IIdentity identity)
        {
            if (string.IsNullOrEmpty(entry))
            {
                throw new ArgumentException(SR.GetString(SR.InvalidLogEntry), "entry");
            }

            if (identity == null)
            {
                throw new ArgumentNullException("identity");
            }

            // establish an instance of the currently configured logging provider.
            LoggingProviderBase provider = LoggingProviderBase.CreateInstance();

            // create a new thread to publish the log entry.
            Thread thread = new Thread(new ParameterizedThreadStart(provider.Log));

            // create a new instance of the LoggingContext class with surrounding information regarding the log entry.
            LoggingContext context = new LoggingContext(
                                                        entry,
                                                        Assembly.GetCallingAssembly(),
                                                        Process.GetCurrentProcess(),
                                                        Thread.CurrentThread,
                                                        priority,
                                                        type,
                                                        identity,
                                                        AppDomain.CurrentDomain);

            // publish the log entry using the configured exception provider.
            thread.Start(context);

            // block the calling thread until the thread terminates.
            thread.Join();

            return context.Id;
        }

        #endregion
    }
}
